package com.micro.ai.commons.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

/**
 * 性能监控切面
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Aspect
@Component
public class PerformanceAspect {

    /**
     * 定义切点：所有Controller方法
     */
    @Pointcut("execution(* com.micro.ai..controller..*(..))")
    public void controllerPointcut() {
    }

    /**
     * 定义切点：所有Service方法
     */
    @Pointcut("execution(* com.micro.ai..service..*(..))")
    public void servicePointcut() {
    }

    /**
     * 性能监控：Controller方法
     */
    @Around("controllerPointcut()")
    public Object monitorController(ProceedingJoinPoint joinPoint) throws Throwable {
        return monitorPerformance(joinPoint, "Controller");
    }

    /**
     * 性能监控：Service方法
     */
    @Around("servicePointcut()")
    public Object monitorService(ProceedingJoinPoint joinPoint) throws Throwable {
        return monitorPerformance(joinPoint, "Service");
    }

    /**
     * 性能监控通用方法
     */
    private Object monitorPerformance(ProceedingJoinPoint joinPoint, String layer) throws Throwable {
        long startTime = System.currentTimeMillis();
        
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        
        // 设置MDC上下文
        String requestId = MDC.get("requestId");
        if (requestId != null) {
            MDC.put("performance", layer + "." + className + "." + methodName);
        }
        
        try {
            // 执行方法
            Object result = joinPoint.proceed();
            
            // 计算执行时间
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;
            
            // 记录性能日志
            if (executionTime > 1000) {
                log.warn("性能警告 - {}: {}.{}, 执行时间: {}ms", layer, className, methodName, executionTime);
            } else if (executionTime > 500) {
                log.info("性能提示 - {}: {}.{}, 执行时间: {}ms", layer, className, methodName, executionTime);
            } else {
                log.debug("性能正常 - {}: {}.{}, 执行时间: {}ms", layer, className, methodName, executionTime);
            }
            
            return result;
        } catch (Exception e) {
            // 计算执行时间
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;
            
            // 记录异常性能日志
            log.error("性能异常 - {}: {}.{}, 执行时间: {}ms, 异常: {}", 
                layer, className, methodName, executionTime, e.getMessage());
            
            throw e;
        }
    }
}
